import { VMEntity } from "../VMEntity";
import * as cc from "cc";
import { VM } from "../VMMgr";

declare const CC_EDITOR;
declare const CC_DEV;



export class VMButtonClickEntity extends VMEntity{
    // @ts-ignore
    observerAttr: VMButtonAttr;
    isArray = false;
    onBind() {
        if(CC_EDITOR){ return; }
        this.node.on(cc.Node.EventType.TOUCH_END,this.onBtnClick,this);
    }
    onUnBind() {
        if(CC_EDITOR){ return; }
        this.node && this.node.off(cc.Node.EventType.TOUCH_END,this.onBtnClick,this);
    }
    onValueInit() {
        if(CC_EDITOR){ return; }
        let _watchPath = this.observerAttr.watchPath;
        if(!Array.isArray(_watchPath)){
            _watchPath = [_watchPath];
        }else{
            this.isArray = true;
        }
        let max = _watchPath.length;
        for (let i = 0; i < max; i++) {
            let val = VM.getValue(_watchPath[i], null);
            this.templateValuesCache[i] = val;
        }
    }
    onStart() {
        if(CC_EDITOR){ return; }
        
    }

    onBtnClick(){
        if(CC_EDITOR){ return; }
        let oldValue;        
        let _watchPath = this.observerAttr.watchPath;
        let isArray = this.isArray;
        if(isArray){
            oldValue = [...this.templateValuesCache];
        }else{
            oldValue = this.templateValuesCache[0];
        }

        let newValue =  this.observerAttr.operation({
            currentValue: oldValue,
            watchPath: _watchPath
        });

        if(isArray){
            if(!Array.isArray(newValue)){
                console.warn(`VMFactory->VMButtonEntity [ ${this.node.name} ] operation  returned value must be array !!`);                
                return;
            }
            let maxj = newValue.length;
            if(_watchPath.length != maxj){
                console.warn(`VMFactory->VMButtonEntity [ ${this.node.name} ] operation  returned value array length must == watchPath.length , now it's not  [${maxj}]:[${_watchPath.length}]`);                
                return;
            }
            for (let j = 0; j < maxj; j++) {
                // 这里不用 oldValue[i] 是为了防止用户在原先数据基础上做修改，会出现新旧数据一致导致无法更新的问题
                // this.setValue(_watchPath[j], newValue[j],oldValue[j],j);
                this.setValue(_watchPath[j], newValue[j],this.templateValuesCache[j],j);
            }
        }else{
            this.setValue(_watchPath as string, newValue,oldValue,0);
        }
    }

    setValue(watchPath: string,newValue: any,oldValue: any,index){
        if(typeof newValue == 'number'){
            if(typeof this.observerAttr.min != 'undefined'){
                newValue = Math.max(newValue,this.val(this.observerAttr.min,index));
            }
            if(typeof this.observerAttr.max != 'undefined'){
                newValue = Math.min(newValue,this.val(this.observerAttr.max,index));
            }
        }else{
            if(typeof this.observerAttr.min != 'undefined' || typeof this.observerAttr.max != 'undefined'){
                cc.warn(`VMFactory->VMButtonEntity [ ${this.node.name} ] watchPath [${watchPath}] is not number, [min] or [max] unjoined operation !`); 
            }
        }

        if(oldValue != newValue){
            this.templateValuesCache[index] = newValue;
            VM.setValue(watchPath as string, newValue);
        }        
    }

    private val(param: number | number[] |  ((index?: number)=> number),index: number){
        if(typeof param == 'number'){
            return param;
        }else if(typeof param == 'function'){
            return param(index);
        }else if(Array.isArray(param)){
            return param[index];
        }
        return 0;
    }
    protected onValueChanged(newValue: any, oldValue: any, pathArr: readonly string[]) {
        if(CC_EDITOR){ return; }
        // 更新缓存值
        let _watchPath = this.observerAttr.watchPath;
        let isArray = this.isArray;
        if(isArray){    
            _watchPath = _watchPath as [];
            let path = pathArr.join('.');
            //寻找缓存位置
            let index = _watchPath.findIndex(v => v === path);

            if (index >= 0) {
                //如果是所属的路径，就可以替换文本了
                this.templateValuesCache[index] = newValue; //缓存值
            }
        }else{            
            this.templateValuesCache[0] = newValue; //缓存值
        }
    }
    onCheckProperty(): boolean {
        return true;
    }
}

